---
title: 'Tracing'
description: 'Configure Phoenix/Langfuse tracing and trajectory recording'
---

Droidrun provides multiple monitoring capabilities:

1. **LLM Tracing** - Real-time execution tracing via Arize Phoenix or Langfuse
2. **Trajectory Recording** - Local screenshots and UI state for debugging

## Quick Reference

```sh
# Enable Phoenix tracing
droidrun run "task" --tracing

# Enable trajectory recording
droidrun run "task" --save-trajectory step
```

---

## LLM Tracing

Droidrun supports two tracing providers for real-time monitoring of LLM calls, agent execution, and tool invocations:

- **Arize Phoenix** (default) - Open-source observability platform
- **Langfuse** - LLM engineering platform with cloud and self-hosted options

Use tracing to debug agent behavior, monitor token usage, and analyze execution flow.

---

### Arize Phoenix Tracing

### Setup

**1. Install Phoenix:**

```sh
uv pip install arize-phoenix
```

**2. Start Phoenix server:**

```sh
phoenix serve
```

The server starts at `http://localhost:6006` and provides a web UI for viewing traces.

**3. Enable tracing in Droidrun:**

**Via CLI:**

```sh
droidrun run "Open settings" --tracing
```

**Via config.yaml:**

```yaml
tracing:
  enabled: true
```

**Via code:**

```python
from droidrun import DroidAgent, DroidrunConfig

config = DroidrunConfig()
config.tracing.enabled = True

agent = DroidAgent(goal="Open settings", config=config)
agent.run()
```

**4. View traces:**

Navigate to `http://localhost:6006` to see:
- LLM calls with prompts, responses, and token counts
- Agent workflow execution (Manager, Executor, CodeAct)
- Tool invocations and their results
- Execution timings and errors

For more on using Phoenix, see the [Arize Phoenix documentation](https://docs.arize.com/phoenix).

**Phoenix Configuration**

Set environment variables to customize Phoenix:

```sh
# Custom Phoenix server URL (default: http://127.0.0.1:6006)
export phoenix_url=http://localhost:6006

# Project name for organizing traces
export phoenix_project_name=my_droidrun_project
```

<Note>
Environment variable names are lowercase: `phoenix_url` and `phoenix_project_name`.
</Note>

---

### Langfuse Tracing

Langfuse provides LLM observability with features like session tracking, user analytics, and cost monitoring.

**Setup**

**1. Get Langfuse credentials:**
- **Cloud**: Sign up at [cloud.langfuse.com](https://cloud.langfuse.com)
- **Self-hosted**: Deploy using [Langfuse docs](https://langfuse.com/docs/deployment/self-host)

**2. Configure Droidrun:**

**Via environment variables:**
```sh
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_HOST=https://cloud.langfuse.com
```

**Via config.yaml:**
```yaml
tracing:
  enabled: true
  provider: langfuse
  langfuse_secret_key: sk-lf-...
  langfuse_public_key: pk-lf-...
  langfuse_host: https://cloud.langfuse.com
  langfuse_user_id: user@example.com  # Optional: track by user
  langfuse_session_id: ""              # Optional: custom session ID
```

**Via code:**
```python
from droidrun import DroidAgent, DroidrunConfig, TracingConfig

config = DroidrunConfig(
    tracing=TracingConfig(
        enabled=True,
        provider="langfuse",
        langfuse_secret_key="sk-lf-...",
        langfuse_public_key="pk-lf-...",
        langfuse_host="https://cloud.langfuse.com",
        langfuse_user_id="user@example.com",
    )
)

agent = DroidAgent(goal="Open settings", config=config)
await agent.run()
```

**3. View traces:**

Navigate to your Langfuse dashboard to see:
- LLM calls with prompts, completions, and token usage
- Agent execution traces and nested workflows
- Session-based analytics and cost tracking
- User-level metrics (if `langfuse_user_id` is set)

For more on using Langfuse, see the [Langfuse documentation](https://langfuse.com/docs).

---

## Trajectory Recording

Trajectory recording saves screenshots and UI state locally for offline debugging and analysis. Unlike telemetry (sent to PostHog) and tracing (sent to Phoenix), trajectories stay on your machine.

### Recording Levels

| Level | What's Saved | When to Use |
|-------|--------------|-------------|
| `none` (default) | Nothing | Production use, saves disk space |
| `step` | Screenshot + state per agent step | General debugging, recommended for most use cases |
| `action` | Screenshot + state per atomic action | Detailed debugging, captures every tap/swipe/type |

**Note:** `action` level generates significantly more files than `step` level.

### Enable Recording

**Via CLI:**

```sh
droidrun run "Open settings" --save-trajectory step
```

**Via config.yaml:**

```yaml
logging:
  save_trajectory: step  # none | step | action
```

**Via code:**

```python
from droidrun import DroidAgent, DroidrunConfig

config = DroidrunConfig()
config.logging.save_trajectory = "action"

agent = DroidAgent(goal="Open settings", config=config)
agent.run()
```

### Output Location

Trajectories are saved to `trajectories/` in your working directory:

```
trajectories/
└── 2025-10-17_14-30-45_open_settings/
    ├── step_000_screenshot.png
    ├── step_000_state.json
    ├── step_001_screenshot.png
    └── step_001_state.json
```

Each trajectory folder contains:
- **Screenshots** - PNG images of the device screen at each step/action
- **State files** - JSON files with:
  - UI accessibility tree (element hierarchy with IDs, text, bounds)
  - Action executed (e.g., `click(5)`, `type("hello", 3)`)
  - Agent reasoning and step number
  - Device state (current app package, activity)

Use these files to:
- Debug why the agent made specific decisions
- Replay failed executions
- Analyze UI element detection issues
- Build training datasets for agent improvement

---

## Related Documentation

- [Configuration System](/sdk/configuration) - Configure tracing and telemetry settings
- [Events and Workflows](/concepts/events-and-workflows) - Build custom monitoring integrations
- [CLI Usage](/guides/cli) - Command-line flags for monitoring
